/**
 *******************************************************************************
 * @FileName  : hci_tr_main.c
 * @Author    : GaoQiu
 * @CreateDate: 2020-09-10
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *
 *******************************************************************************
 *
 * The information contained herein is confidential and proprietary property of
 * GaoQiu and is available under the terms of Commercial License Agreement
 * between GaoQiu and the licensee in separate contract or the terms desc ribed
 * here-in.
 *
 * This heading MUST NOT be removed from this file.
 *
 * Licensees are granted free, non-transferable use of the information in this
 * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
 *
 *******************************************************************************
 */
#include "hci_tr_main.h"
#include "hci_tr_api.h"
#include "hci_tr_h4.h"
#include "hci_tr_h5.h"
#include "hci_slip.h"
#include "hci_h5.h"
#include "hci_tr_def.h"

#include "stack/controller/lhci_api.h"
#include "platform/platform.h"

extern volatile uint8_t isUartTxDone;

void HCI_TR_Init(void)
{
#if HCI_TR_MODE == HCI_TR_H4
	HCI_TR_H4Init(LHCI_GetRxCmdFifo(), LHCI_GetRxAclFifo());

#elif HCI_TR_MODE == HCI_TR_H5
	HCI_TR_H5Init();
	HCI_Slip_Init();
	HCI_H5_Init(LHCI_GetRxCmdFifo(), LHCI_GetRxAclFifo(), LHCI_GetTxFifo());

#elif HCI_TR_MODE == HCI_TR_USB
	//TODO:

#endif
}

void LHCI_TxHandler(void)
{
	/* Check if there is data to process. */
	fifo_t *pFifo = LHCI_GetTxFifo();
	if(FIFO_Length(pFifo) == 0){
		return;
	}

	/* Check if UART is idle. UART is idle when isUartTxDone == 1. */
	if(!isUartTxDone){
		return;
	}
	isUartTxDone = 0;//must place there, because IRQ may preempt it. [!!! important]

	/* Push data to UART DMA. */
	uint8_t *pBuf = FIFO_GetReadBuf(pFifo);
	if(pBuf)
	{
		//TRACK_DATA(pBuf+4, pBuf[0]);

		if(UART_SendDataByDma(pBuf)){
			FIFO_MoveToNextReadBuf(pFifo);
		}
	}
}

/**
 * @brief : HCI transport main loop.
 * @param : none.
 * @param : none.
 */
void HCI_TR_TaskStart(void)
{
#if HCI_TR_MODE == HCI_TR_H4
	/* H4 Transport RX handle */
	HCI_TR_H4RxHandler();

	LHCI_RxHandler(); /* LHCI RX handle */
	LHCI_TxHandler(); /* LHCI TX handle */

#elif HCI_TR_MODE == HCI_TR_H5
	/* H5 Transport RX handle */
	HCI_TR_H5RxHandler();

	LHCI_RxHandler();
	//LHCI_TxHandler(); /* This is not needed because the H5 takes over the handling of the LHCI TX FIFO. */

	/* H5 handle */
	HCI_H5_Poll();

#elif HCI_TR_MODE == HCI_TR_USB
	//TODO:
#endif
}

/**
 * @brief : HCI IRQ handler.
 * @param : none.
 * @param : none.
 */
RAM_CODE void HCI_TR_IRQHandler(void)
{
#if HCI_TR_MODE == HCI_TR_H4
	HCI_TR_H4IRQHandler();

#elif HCI_TR_MODE == HCI_TR_H5
	HCI_TR_H5IRQHandler();

#elif HCI_TR_MODE == HCI_TR_USB
	//TODO:
#endif
}

